package cn.itcast.web.controller.cargo;

import cn.itcast.domain.ResultInfo;
import cn.itcast.domain.cargo.*;
import cn.itcast.domain.system.User;
import cn.itcast.service.cargo.ContractService;
import cn.itcast.service.cargo.ExportProductService;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductVo;
import cn.itcast.vo.ExportResult;
import cn.itcast.vo.ExportVo;
import cn.itcast.web.controller.BaseController;
import cn.itcast.web.utils.BeanMapUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.*;

@Controller
@RequestMapping("/cargo/export")
public class ExportController extends BaseController {


    @Reference
    private ContractService contractService;


    @Reference
    private ExportService exportService;

    @Reference
    private ExportProductService exportProductService;


    /*
        url:/cargo/export/contractList.do
        作用： 进入到合同状态为1列表中
        参数： 无
        返回值： cargo/export/export-contractList.jsp

     */
    @RequestMapping("/contractList")
    public String contractList(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize) {

        //找到状态为1的购销合同列表
        ContractExample contractExample = new ContractExample();
        //添加条件
        contractExample.createCriteria().andStateEqualTo(1);
        //按照创建时间排序
        contractExample.setOrderByClause("create_time desc");
        PageInfo<Contract> pageInfo = contractService.findByPage(contractExample, pageNum, pageSize);
        //2. 存储到域
        request.setAttribute("pageInfo", pageInfo);
        return "cargo/export/export-contractList";
    }


    /*
       url:/cargo/export/list.do
       作用： 进入报运单列表
       参数： 无
       返回值： cargo/export/export-list.jsp

    */
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize) {

        //找到报运单列表
        ExportExample exportExample = new ExportExample();
        //按照创建时间排序
        exportExample.setOrderByClause("create_time desc");
        //添加条件，当前登陆者所属的企业
        exportExample.createCriteria().andCompanyIdEqualTo(getLoginUserCompanyId());

        PageInfo<Export> pageInfo = exportService.findByPage(exportExample, pageNum, pageSize);
        //2. 存储到域
        request.setAttribute("pageInfo", pageInfo);
        return "cargo/export/export-list";
    }

    /*
      url:/cargo/export/toExport.do
      作用： 进入添加报运单的页面
      参数： id 生成报运单的购销合同的id，是可能会存在多个id
      返回值： cargo/export/export-toExport

   */
    @RequestMapping("/toExport")
    public String toExport(String id) {
        //把购销合同的id存储到请求域中
        request.setAttribute("id",id);
        return "cargo/export/export-toExport";
    }


    /*
       url：/cargo/export/edit.do
       作用：保存添加与保存修改报运单
       参数：报运单对象
       返回值： 报运单列表
    */
    @RequestMapping("/edit")
    public String edit(Export export){
        //补充数据，因为这些数据是来自于登陆者
        String companyId = getLoginUserCompanyId();
        String companyName= getLoginUserCompanyName();
        export.setCompanyId(companyId);
        export.setCompanyName(companyName);
        //报运单的创建人
        export.setCreateBy(getLoginUser().getId());
        //报运单创建人所属的部门
        export.setCreateDept(getLoginUser().getDeptId());

        //1.判断export是否携带id过来，如果没有携带则是添加
        if(StringUtils.isEmpty(export.getId())){
            exportService.save(export);
        }else {
            //2. 如果携带id过来则是修改
            exportService.update(export);
        }
        return "redirect:/cargo/export/list.do";
    }

    /*
       url：/cargo/export/toUpdate.do?id=31df2a93-10ae-404e-a83f-4225119d8600
       作用：进入修改报运单页面
       参数：id 报运单的id
       返回值：cargo/export/export-update.jsp
    */
    @RequestMapping("/toUpdate")
    public String toUpdate(String id){
        //找到报运单对象，存储到请求域中
        Export export = exportService.findById(id);
        request.setAttribute("export",export);

        //找到报运商品对象，存储到请求域中
        ExportProductExample exportProductExample= new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);
        request.setAttribute("eps",exportProductList);

        return "cargo/export/export-update";

    }




    /*
       url：/cargo/export/toView.do?id=31df2a93-10ae-404e-a83f-4225119d8600
       作用：查看报运单
       参数：id 报运单的id
       返回值：cargo/export/export-view
    */
    @RequestMapping("/toView")
    public String toView(String id){
        Export export = exportService.findById(id);
        //存储到请求域中
        request.setAttribute("export",export);
        return "cargo/export/export-view";
    }


    /*
    url：/cargo/export/submit.do?id=31df2a93-10ae-404e-a83f-4225119d8600
    作用：提交报运单
    参数：id 报运单的id
    返回值：报运单列表
 */
    @RequestMapping("/submit")
    public String submit(String id){

        Export export = exportService.findById(id);
        if (export.getState() != 0){
            request.setAttribute("error","该保运单已提交");
            return "forward:/error-info.jsp";
        }
        //修改报运单的状态
        export.setState(1);
        exportService.update(export);
        return "redirect:/cargo/export/list.do";
    }


    /*
     url：/cargo/export/cancel.do?id=31df2a93-10ae-404e-a83f-4225119d8600
     作用：取消报运单
     参数：id 报运单的id
     返回值：报运单列表
    */
    @RequestMapping("/cancel")
    public String cancel(String id){
        Export export = exportService.findById(id);
        if (export.getState() != 1){
            request.setAttribute("error","只有已上报状态的报运单才能取消");
            return "forward:/error-info.jsp";
        }
        //修改报运单的状态
        export.setState(0);
        exportService.update(export);
        return "redirect:/cargo/export/list.do";
    }



    /*
   url：/cargo/export/exportE.do?id=31df2a93-10ae-404e-a83f-4225119d8600
   作用：电子报运
   参数：id 报运单的id
   返回值：报运单列表
*/
    @RequestMapping("/exportE")
    public String exportE(String id){
        //1. 找到报运单
        Export export = exportService.findById(id);

        //2. 创建ExportVo对象
        ExportVo exportVo = new ExportVo();

        //3. 把报运单属性值拷贝到ExportVo里面
        BeanUtils.copyProperties(export,exportVo);
        //补充信息
        exportVo.setExportId(export.getId());

        //4. 找到报运单对应的商品
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);

        //5. 遍历商品把商品的信息拷贝到ExportProductVo对象中
        for (ExportProduct exportProduct : exportProductList) {
            //每一个商品对应ExportProductVo
            ExportProductVo exportProductVo = new ExportProductVo();
            //6. 把ExportProductVo对象信息添加到exportVo对象
            BeanUtils.copyProperties(exportProduct,exportProductVo);
            //补充信息
            exportProductVo.setExportProductId(exportProduct.getId());
            //把商品的信息添加products属性中
            exportVo.getProducts().add(exportProductVo);
        }

        //7. 调用海关平台的接口，把ExportVo对象传递过去
        WebClient.create("http://localhost:9090/ws/export/user").post(exportVo);

        //8. 查看海关审核报运单的结果，
        ExportResult exportResult = WebClient.create("http://localhost:9090/ws/export/user/" + id).get(ExportResult.class);

        //9、 根据海关返回的结果去更新你的报运单的状态以及商品的税收。
        exportService.updateExportState(exportResult);


        return "redirect:/cargo/export/list.do";
    }


    @Autowired
    private DataSource dataSource;


    /*
       url：/cargo/export/exportPdf.do?id=31df2a93-10ae-404e-a83f-4225119d8600
       作用：下载电子报运pdf模式
       参数：id 报运单的id
       返回值：没有返回值，下载
    */
    @RequestMapping("/exportPdf")
    @ResponseBody
    public void exportPdf(String id) throws Exception {
        //通知浏览器以附件下载的形式处理
        response.setHeader("content-disposition","attachment;filename=export.pdf");


        //1. 获取到模板的输入流
        InputStream inputStream = session.getServletContext().getResourceAsStream("/jasper/export.jasper");

        //2. 根据id查找报运单
        Export export = exportService.findById(id);

        //3. 把报运单的对象转换为map
        Map<String, Object> map = BeanMapUtils.beanToMap(export);

        //4. 找到报运单的商品
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);

        //5. 把报运单的商品存储到数据源中
        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(exportProductList);

        JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream, map,dataSource);


        //6. 把pdf输出即可
        JasperExportManager.exportReportToPdfStream(jasperPrint,response.getOutputStream());


    }

    @RequestMapping("/packing")
    public String packing(@RequestParam("id") List<String> ids){

        //将获取的合同id交由exportService处理，exportService应返回ResultInfo
        ResultInfo resultInfo = exportService.checkPackingInfo(ids);
        //对ResultInfo的success进行判断
        if (resultInfo.getSuccess()){
            //若结果为true，data存储到请求域中
            request.setAttribute("packing",resultInfo.getData());
            //跳转到添加装箱信息页
            return "cargo/export/export-packing";
        }else {
            //若结果为fasle，跳转到失败页
            request.setAttribute("error",resultInfo.getMsg());
            return "forward:/error-info.jsp";
        }

    }
}
